package com.ericsson.epc.modules.ebmAutoCollector.thread;


import com.ericsson.common.util.DateUtils;
import com.ericsson.common.util.LogFileName;
import com.ericsson.common.util.LoggerUtils;
import com.ericsson.common.util.ValidateUtil;
import com.ericsson.epc.modules.ebmAutoCollector.entity.EbmAutoCInfo;
import com.ericsson.epc.modules.ebmAutoCollector.entity.Net;
import com.ericsson.epc.modules.ebmAutoCollector.service.EbmService;
import org.slf4j.Logger;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;


public class EbmSignalThread implements Runnable {

    private Logger log = LoggerUtils.Logger(LogFileName.EbmAutoCollectorJob);
    /*private static final String ebmSignalPath = PropertiesUtil.getProperty("ebmSignalPath");
    private static final String ccsccdestPath = PropertiesUtil.getProperty("ccsccdestPath");*/
    private EbmAutoCInfo ebmAutoC;
    private String ip;
    private String username;
    private String password;
    private String cc;
    private String scc;
    private String lcpt;
    private int mnoh;
    private String utd;
    private Long netid;
    private String netName;
    private EbmService ebmService;
    private int sleepTime;
    private String endtime;
    private String ebmSignalPath;
    private String ccsccdestPath;
    private String pId;


    public EbmSignalThread(Net net, EbmAutoCInfo ebmAutoC, String cc, String scc, Map<String,Object> paramMap,
                           EbmService ebmService, String endtime,String pId,int mnoh,String lcpt){
        this.ebmAutoC = ebmAutoC;
        this.ip = net.getIpadr();
        this.username = net.getUsername1();
        this.password = net.getPassword1();
        this.cc = cc;
        this.scc = scc;
        this.netid = net.getId();
        this.netName = net.getFname();
        this.lcpt = lcpt;
        this.mnoh = mnoh;
        this.utd = (String)((Map)paramMap.get("NB_UTD")).get("value");
        this.sleepTime = Integer.parseInt((String)((Map)paramMap.get("NB_SLEEP")).get("value"));
        this.ebmSignalPath = (String)((Map)paramMap.get("ebmSignalPath")).get("value");
        this.ccsccdestPath = (String)((Map)paramMap.get("ccsccdestPath")).get("value");
        this.ebmService = ebmService;
        this.endtime = endtime;
        this.pId = pId;
    }

    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        log.info(threadName+" ==== EbmSignalThread start ==== ");
        Process proc = null;
        String[] cmd = new String[3];
        cmd[0] = "sh";
        cmd[1] = "-c";
        //校验referenceid是否是空，如果为空就正常下发脚本1、2、3
        if(ValidateUtil.isEmpty(ebmAutoC.getReferenceid())) {
            log.info(threadName+" ==== refid is null,first execute script 1 ====");
            String referenceId = firstSendCmd(proc, cmd, netid,threadName);
            //ebmService.insertLog(cc,scc,netid,referenceId);
            ebmService.insertReferenceId(ebmAutoC.getId(), referenceId);
            try {
                log.info(threadName+" ==== begin sleep : "+Integer.parseInt(utd)*60+" s");
                Thread.sleep(Integer.parseInt(utd)*1000*60);//睡眠时间跟脚本1执行时间参数一致
                log.info(threadName+" ==== end sleep : ");
            } catch (InterruptedException e) {
                log.error(threadName+" EbmSignalThread run error ",e);
            }
            boolean f = secondSendCmd(proc, cmd, netid,referenceId,threadName);
            //如果f = true 表示抓包状态为finished，目前 f = true 有1种情况，一种是finished
            if(f){
                thirdSendCmd(proc, cmd, netid,referenceId,threadName);
            }//f = false 一种是running超时，抓包时间超过配置的结束时间
        }else{
            //判断当前脚本1执行的状态是running还是finished
            //String resultStatus = getSecondSendCmdResult(proc,cmd, netid,ebmAutoC.getReferenceid(),threadName);
              String resultStatus = ebmService.getStatus(ebmAutoC.getReferenceid(),netid);
            if(resultStatus.equals("1")){
                log.info(threadName+" ==== resultStatus is running");
                //此时上一次的这个网元第一脚本还没执行完成，所以啥也不干
            }else{
                //上一次的这个网元全部执行完了，就执行第二次轮询
                log.info(threadName+" ==== resultStatus is "+resultStatus);
                String referenceId = firstSendCmd(proc, cmd, netid,threadName);
                //ebmService.insertLog(cc,scc,netid,referenceId);
                ebmService.insertReferenceId(ebmAutoC.getId(), referenceId);
                try {
                    log.info(threadName+" ==== begin sleep : "+Integer.parseInt(utd)*60+" s ");
                    Thread.sleep(Integer.parseInt(utd)*1000*60);//睡眠时间跟脚本1执行时间参数一致
                    log.info(threadName+" ==== end sleep : ");
                } catch (InterruptedException e) {
                    log.error(threadName+" EbmSignalThread run error " + threadName,e);
                }
                boolean f = secondSendCmd(proc, cmd, netid,referenceId,threadName);
                if(f){
                    thirdSendCmd(proc, cmd, netid,referenceId,threadName);
                }
            }
        }
        log.info(threadName+" ==== EbmSignalThread end ==== ");
    }

    //执行脚本1
    public String firstSendCmd(Process proc,String cmd[],Long netid,String threadName){
        String ref = "";
        cmd[2] = ebmSignalPath + "cc_scc_trigger.pl -ip " + ip + " -user " + username + " -password " + password + " -lcpt " + lcpt + " -cc " +
                cc + " -scc " + scc + " -mnoh " + mnoh + " -utd " + utd;
        try {
            log.info(threadName+" ==== firstSendCmd:" +cmd[2]);
            proc = Runtime.getRuntime().exec(cmd);
            ebmService.insertStartTime(ebmAutoC.getId());
            BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = null;
            while((line = br.readLine())!=null){
                //log.info(threadName+" ==== firstSendCmd:"+line);
                if(line.contains("Trigger Ref is")){
                    ref = line.split(":")[1];
                    log.info(threadName+" ==== ref id:"+ref);
                    break;
                }
                if(line.contains("failure")){
                    break;
                }
            }
        } catch (IOException e) {
            log.error(threadName+" EbmSignalThread firstSendCmd exception",e);
        } finally {
            log.info(threadName+" ==== firstSendCmd end ====");
            try {
                proc.waitFor();
            } catch (InterruptedException e) {
                log.error(threadName+" EbmSignalThread firstSendCmd exception",e);
            }
            proc.destroy();
        }
        return ref;
    }

    public String getSecondSendCmdResult(Process proc,String cmd[],Long netid,String referenceId,String threadName){
        cmd[2] = ebmSignalPath + "get_trigger_status.pl -ip " + ip + " -user " + username + " -password " + password + " -ref " + referenceId;
        log.info(threadName+" ==== getSecondSendCmdResult:" +cmd[2]);
        boolean flag = true;
        String result = "";
            try {
                proc = Runtime.getRuntime().exec(cmd);
                BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                String line = null;
                while((line = br.readLine())!=null){
                    log.info(threadName+" ==== getSecondSendCmdResult:"+line);
                    if(line.contains("Trigger Status:running")){
                        result = "running";
                        break;
                    }
                    if(line.contains("Trigger Status:finished")){
                        result = "finished";
                        break;
                    }
                    if(line.contains("Error occur")){
                        result = "error";
                        break;
                    }
                }
            } catch (IOException e) {
                log.error(threadName+ " EbmSignalThread getSecondSendCmdResult exception",e);
            } finally {
                log.info(threadName+ " ==== getSecondSendCmdResult end ====");
                try {
                    proc.waitFor();
                } catch (InterruptedException e) {
                    log.error(threadName+" EbmSignalThread getSecondSendCmdResult exception",e);
                }
                proc.destroy();
            }
        return result;
    }

    //执行脚本2
    public boolean secondSendCmd(Process proc,String cmd[],Long netid,String referenceId,String threadName){
        boolean returnFlag = false;
        cmd[2] = ebmSignalPath + "get_trigger_status.pl -ip " + ip + " -user " + username + " -password " + password + " -ref " + referenceId;
        log.info(threadName+" ==== secondSendCmd:" +cmd[2]);
        boolean flag = true;
        while(flag){
            try {
                proc = Runtime.getRuntime().exec(cmd);
                BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                String line = null;
                while((line = br.readLine())!=null){
                    //log.info(threadName+" ==== secondSendCmd:"+line);
                    if(line.contains("Trigger Status:running")){
                        //如果状态是running,睡眠10s，重新循环发脚本2（查询抓包状态）
                        log.info(threadName+" ===== line:"+line + " begin sleep:"+sleepTime*1000);
                        Thread.sleep(sleepTime*1000);
                        log.info(threadName+" ===== end sleep ====");
                        break;
                    }
                    if(line.contains("Trigger Status:finished")){
                        log.info(threadName+" ===== line:"+line);
                        ebmService.updateStatus(ebmAutoC.getId());
                        flag = false;
                        returnFlag = true;
                        break;
                    }
                    if(line.contains("Error occur")){
                        flag = false;
                        break;
                    }
                }
                //当抓包已到结束的时间，抓包状态还是running
                if(DateUtils.getDateTime().compareTo(DateUtils.getAfterNMinDateTime(endtime,sleepTime,"yyyy-MM-dd HH:mm:ss"))>=0){
                    fourSendCmd(proc,cmd,netid,referenceId,threadName);
                    ebmService.updateStatus(ebmAutoC.getId());
                    thirdSendCmd(proc,cmd,netid,referenceId,threadName);
                    flag = false;
                    returnFlag = true;
                    break;
                }
            } catch (IOException e) {
                log.error(threadName + " EbmSignalThread secondSendCmd exception",e);
            } catch (InterruptedException e) {
                log.error(threadName + " EbmSignalThread secondSendCmd exception",e);
            } finally {
                log.info(threadName + " ==== SecondSendCmd end ====");
                try {
                    proc.waitFor();
                } catch (InterruptedException e) {
                    log.error(threadName + " EbmSignalThread firstSendCmd exception",e);
                }
                proc.destroy();
            }
        }
        return returnFlag;
    }

    //执行脚本3
    public void thirdSendCmd(Process proc,String cmd[],Long netid,String referenceId,String threadName){
        int time_span = ebmService.getTimeDifference(referenceId,netid);
        String starttime = ebmService.getStartTime(referenceId,netid);
        //String date = starttime.replaceAll(" ","_").replaceAll("-","").replaceAll(":","").substring(0,11);
        String date = DateUtils.dateRoll(0);
        String endtime = ebmService.getEndTime(referenceId,netid);
        String interval = starttime.substring(11,19).replaceAll(":","") + "-" + endtime.substring(11,19).replaceAll(":","");
        cmd[2] = ebmSignalPath + "get_pcap_files.py -ip " + ip + " -user " + username + " -password " + password + " -ref " + referenceId +
                " -time_span " + time_span + " -dest_folder " +
                ccsccdestPath + date + File.separator + "cc_" + cc + "_scc_" + scc + "_" + pId + File.separator + netName + File.separator + interval;
        log.info(threadName + " ==== thirdSendCmd:" +cmd[2]);
        try {
            proc = Runtime.getRuntime().exec(cmd);
            BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = null;
            while((line = br.readLine())!=null){
                //log.info(threadName+" ==== thirdSendCmd:"+line);
                if(line.contains("Completed!")){
                    break;
                }
            }
        } catch (IOException e) {
            log.error(threadName + " EbmSignalThread thirdSendCmd exception",e);
        } finally {
            log.info(threadName + " ==== thirdSendCmd end ==== ");
            try {
                proc.waitFor();
            } catch (InterruptedException e) {
                log.error(threadName +" EbmSignalThread thirdSendCmd exception",e);
            }
            proc.destroy();
        }
    }

    //执行脚本4
    public void fourSendCmd(Process proc,String cmd[],Long netid,String referenceId,String threadName){
        cmd[2] = ebmSignalPath + "sendcmd_mme.pl -ip " + ip + " -user " + username + " -password " + password + " -cmd " +
                "'gsh action_ue_trace_trigger_stop -utrp "+ referenceId + "'";
        log.info(threadName + " ==== fourSendCmd:" +cmd[2]);
        try {
            proc = Runtime.getRuntime().exec(cmd);
        } catch (IOException e) {
            log.error(threadName + " EbmSignalThread fourSendCmd exception",e);
        } finally {
            log.info(threadName + " ==== fourSendCmd end ==== ");
            try {
                proc.waitFor();
            } catch (InterruptedException e) {
                log.error(threadName +" EbmSignalThread fourSendCmd exception",e);
            }
            proc.destroy();
        }
    }
}
